package controllers;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.annotations.SerializedName;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
import play.Logger;
import play.Play;
import play.libs.WS;
import play.libs.WS.WSRequest;
import play.mvc.Controller;

/**
 * Created by xuyang on 2017/6/15.
 */
public class Monitor extends Controller {

    public static void index() {
        metrics();
    }

    public static void metrics() {

        String uptimeString = "";
        MetricsResponse r = null;
        String url = Play.configuration.getProperty("monitor.metrics.url");

        try {

            Logger.debug("Using monitor.metrics.url = " + url);

            WSRequest request = WS.url(url);

            WS.HttpResponse response = request.get();

            JsonElement root = response.getJson();

            // 缓存计数器 com.beamOps.flightMessageProcessor.entity.MsgCachedQueue.pendingMessages.depth
            Gson gson = new Gson();

            r = gson.fromJson(root, MetricsResponse.class);

            Period uptime = new Period(r.gauges.jvmUptime.value.longValue(), PeriodType.seconds());

            PeriodFormatter daysHoursMinutes = new PeriodFormatterBuilder()
                    .appendDays()
                    .appendSuffix(" 天 ")
                    .appendHours()
                    .appendSuffix(" 小时 ")
                    .appendMinutes()
                    .appendSuffix(" 分 ")
                    .appendSeconds()
                    .appendSuffix(" 秒 ")
                    .toFormatter();

            uptimeString = daysHoursMinutes.print(uptime.normalizedStandard());

        } catch (Exception e) {
            Logger.info(e, "读取服务器数据出错 ", url);
            flash("error", "读取服务器数据出错 ");
        }

        render(r, uptimeString);
    }


    public static class MetricsResponse {
        public String version;

        public Gauges gauges;
        public Meters meters;
        public Timers timers;

    }

    public static class Gauges {
        @SerializedName("com.beamOps.flightMessageProcessor.entity.MsgCachedQueue.pendingMessages.depth")
        public Gauge cacheSize;

        @SerializedName("jvm.memory.heap.max")
        public Gauge jvmHeapMax;

        @SerializedName("jvm.memory.heap.used")
        public Gauge jvmHeapUsed;

        @SerializedName("jvm.memory.heap.usage")
        public Gauge jvmHeapUsage;

        @SerializedName("jvm.attribute.uptime")
        public Gauge jvmUptime;
    }

    public static class Meters {


        @SerializedName("com.beamOps.flightMessageProcessor.proxy.MsgProxy.inbound")
        public Meter inbound;

        @SerializedName("com.beamOps.flightMessageProcessor.proxy.MsgProxy.outbound")
        public Meter outbound;
    }

    public static class Timers {

        @SerializedName("com.beamOps.flightMessageProcessor.proxy.MsgProxy.acars-process")
        public Timer acarsProcess;

        @SerializedName("com.beamOps.flightMessageProcessor.proxy.MsgProxy.mq-send")
        public Timer mqSend;

    }


    // 内部类声明

    public static class Gauge {

        public Number value;
    }

    public static class Meter {
        public int count;
        public float m15_rate;
        public float m1_rate;
        public float m5_rate;
        public float mean_rate;
        public String units;
    }

    public static class Timer {
        public int count;
        public float max;
        public float mean;
        public float min;

        public float p50, p75, p95, p98, p99, p999;
        public float stddev;

        public float m15_rate;
        public float m1_rate;
        public float m5_rate;
        public float mean_rate;
        public String duration_units, rate_units;
    }

}
